package com.dave.gd.common.redis.impl.ehcache;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;

import com.dave.gd.common.log.ILogger;
import com.dave.gd.common.log.LoggerFactory;
import com.dave.gd.common.redis.ICacheRepository;
import com.dave.gd.common.util.NumberUtils;
import com.dave.gd.common.util.StringUtils;
import com.dave.gd.common.util.spring.ApplicationContextUtil;

/**
 * Created by linzq on 2014/11/25.
 */
public class EhCacheRepositoryImpl implements ICacheRepository {
    
    private ILogger      LOG          = LoggerFactory.getLogger(EhCacheRepositoryImpl.class);
    
    private CacheManager cacheManager = (CacheManager) ApplicationContextUtil
                                          .getBean("cacheManager");
    
    private Ehcache getCache(String group) {
        Ehcache cache = cacheManager.getEhcache(group);
        if (cache == null) {
            LOG.warn("未创建对应的缓存 [" + group + "]; 创建缺省缓存.");
            cache = cacheManager.addCacheIfAbsent(group);
            LOG.debug("started EHCache region: " + group);
        }
        return cache;
    }
    
    @Override
    public boolean keyExists(String group, String key) {
        Ehcache cache = getCache(group);
        return cache.isKeyInCache(key);
    }
    
    @Override
    public Long delete(String group, String... keys) {
        Ehcache cache = getCache(group);
        Long count = 0L;
        for (String key : keys) {
            cache.remove(key);
            count++;
        }
        return count;
    }
    
    @Override
    public String rename(String group, String oldkey, String newkey) {
        Ehcache cache = getCache(group);
        Element old = cache.get(oldkey);
        if (old != null) {
            cache.remove(oldkey);
            Element elt = new Element(newkey, old.getObjectValue());
            cache.put(elt);
        }
        return newkey;
    }
    
    @Override
    public Long expire(String group, String key, int seconds) {
        Ehcache cache = getCache(group);
        Element old = cache.get(key);
        if (old != null) {
            cache.remove(key);
            Element elt = new Element(key, old.getObjectValue(), Boolean.FALSE,
                NumberUtils.nullToZero(seconds), NumberUtils.nullToZero(seconds));
            cache.put(elt);
        }
        return NumberUtils.nullToLongZero(seconds);
    }
    
    @Override
    public Long ttl(String group, String key) {
        Ehcache cache = getCache(group);
        Element old = cache.get(key);
        if (old != null) {
            Long time = System.currentTimeMillis() - old.getLastUpdateTime();
            return time;
        }
        return 0L;
    }
    
    @Override
    public Long persist(String group, String key) {
        Ehcache cache = getCache(group);
        Element old = cache.get(key);
        if (old != null) {
            cache.remove(key);
            Element elt = new Element(key, old.getObjectValue(), Boolean.TRUE, new Integer(0),
                new Integer(0));
            cache.put(elt);
        }
        return 0L;
    }
    
    @Override
    public String set(String group, String key, String value) {
        Ehcache cache = getCache(group);
        Element elt = new Element(key, value);
        cache.put(elt);
        return value;
    }
    
    @Override
    public String set(String group, String key, String value, int seconds) {
        Ehcache cache = getCache(group);
        Element elt = new Element(key, value, Boolean.FALSE, NumberUtils.nullToZero(seconds),
            NumberUtils.nullToZero(seconds));
        cache.put(elt);
        return value;
    }
    
    @Override
    public String get(String group, String key) {
        Ehcache cache = getCache(group);
        Element elt = cache.get(key);
        if (elt != null) {
            return StringUtils.strnull(elt.getObjectValue());
        }
        return "";
    }
    
    @Override
    public List<String> getMulti(String group, String... keys) {
        List<String> list = new ArrayList<String>();
        Ehcache cache = getCache(group);
        for (String key : keys) {
            Element elt = cache.get(key);
            if (elt != null) {
                list.add(StringUtils.strnull(elt.getObjectValue()));
            }
        }
        return list;
    }
    
    @SuppressWarnings({"unchecked", "rawtypes" })
    @Override
    public List<?> getMultiObject(String group, String... keys) {
        List list = new ArrayList();
        Ehcache cache = getCache(group);
        for (String key : keys) {
            Element elt = cache.get(key);
            if (elt != null) {
                list.add(elt.getObjectValue());
            }
        }
        return list;
    }
    
    @Override
    public String setObject(String group, String key, Serializable value) {
        Ehcache cache = getCache(group);
        Element elt = new Element(key, value);
        cache.put(elt);
        return key;
    }
    
    @Override
    public String setObject(String group, String key, Serializable value, int seconds) {
        Ehcache cache = getCache(group);
        Element elt = new Element(key, value, Boolean.FALSE, NumberUtils.nullToZero(seconds),
            NumberUtils.nullToZero(seconds));
        cache.put(elt);
        return key;
    }
    
    @Override
    public Object getObject(String group, String key) {
        Ehcache cache = getCache(group);
        Element elt = cache.get(key);
        if (elt != null) {
            return elt.getObjectValue();
        }
        return null;
    }
}
